﻿using System;
using System.Collections.Generic;
using System.Drawing;

namespace YArchitech.Controls.ImgListView
{
	internal class ImageListViewLayoutManager
	{
		public Rectangle ClientArea
		{
			get
			{
				return this.mClientArea;
			}
		}

		public ImageListView ImageListView
		{
			get
			{
				return this.mImageListView;
			}
		}

		public Rectangle ItemAreaBounds
		{
			get
			{
				return this.mItemAreaBounds;
			}
		}

		public Rectangle ColumnHeaderBounds
		{
			get
			{
				return this.mColumnHeaderBounds;
			}
		}

		public Size ItemSize
		{
			get
			{
				return this.mItemSize;
			}
		}

		public Size ItemSizeWithMargin
		{
			get
			{
				return this.mItemSizeWithMargin;
			}
		}

		public int Cols
		{
			get
			{
				return this.mCols;
			}
		}

		public int Rows
		{
			get
			{
				return this.mRows;
			}
		}

		public int FirstPartiallyVisible
		{
			get
			{
				return this.mFirstPartiallyVisible;
			}
		}

		public int LastPartiallyVisible
		{
			get
			{
				return this.mLastPartiallyVisible;
			}
		}

		public int FirstVisible
		{
			get
			{
				return this.mFirstVisible;
			}
		}

		public int LastVisible
		{
			get
			{
				return this.mLastVisible;
			}
		}

		public bool UpdateRequired
		{
			get
			{
				return this.mImageListView.View != this.cachedView || this.mImageListView.ViewOffset != this.cachedViewOffset || this.mImageListView.ClientSize != this.cachedSize || this.mImageListView.Items.Count != this.cachedItemCount || this.mImageListView.mRenderer.MeasureItem(this.mImageListView.View) != this.cachedItemSize || this.mImageListView.mRenderer.MeasureColumnHeaderHeight() != this.cachedHeaderHeight || this.mImageListView.mRenderer.MeasureItemMargin(this.mImageListView.View) != this.cachedItemMargin || this.mImageListView.PaneWidth != this.cachedPaneWidth;
			}
		}

		public ImageListViewLayoutManager(ImageListView owner)
		{
			this.mImageListView = owner;
			this.cachedVisibleItems = new Dictionary<Guid, bool>();
			this.vScrollVisible = false;
			this.hScrollVisible = false;
			this.Update();
		}

		public Rectangle GetItemBounds(int itemIndex)
		{
			Point location = this.mItemAreaBounds.Location;
			location.X += this.cachedItemMargin.Width / 2 - this.mImageListView.ViewOffset.X;
			location.Y += this.cachedItemMargin.Height / 2 - this.mImageListView.ViewOffset.Y;
			if (this.mImageListView.View == View.Gallery)
			{
				location.X += itemIndex * this.mItemSizeWithMargin.Width;
			}
			else
			{
				location.X += itemIndex % this.mCols * this.mItemSizeWithMargin.Width;
				location.Y += itemIndex / this.mCols * this.mItemSizeWithMargin.Height;
			}
			return new Rectangle(location, this.mItemSize);
		}

		public Rectangle GetItemBoundsWithMargin(int itemIndex)
		{
			Rectangle itemBounds = this.GetItemBounds(itemIndex);
			itemBounds.Inflate(this.cachedItemMargin.Width / 2, this.cachedItemMargin.Height / 2);
			return itemBounds;
		}

		public void Update()
		{
			this.Update(false);
		}

		public void Update(bool forceUpdate)
		{
			if (this.mImageListView.ClientRectangle.Width == 0 || this.mImageListView.ClientRectangle.Height == 0)
			{
				return;
			}
			if (!forceUpdate && !this.UpdateRequired)
			{
				return;
			}
			this.cachedView = this.mImageListView.View;
			this.cachedViewOffset = this.mImageListView.ViewOffset;
			this.cachedSize = this.mImageListView.ClientSize;
			this.cachedItemCount = this.mImageListView.Items.Count;
			this.cachedItemSize = this.mImageListView.mRenderer.MeasureItem(this.mImageListView.View);
			this.cachedHeaderHeight = this.mImageListView.mRenderer.MeasureColumnHeaderHeight();
			this.cachedItemMargin = this.mImageListView.mRenderer.MeasureItemMargin(this.mImageListView.View);
			this.cachedPaneWidth = this.mImageListView.PaneWidth;
			this.cachedVisibleItems.Clear();
			this.mClientArea = this.mImageListView.ClientRectangle;
			this.mItemAreaBounds = this.mImageListView.ClientRectangle;
			this.mItemSize = this.cachedItemSize;
			this.mItemSizeWithMargin = this.mItemSize + this.cachedItemMargin;
			if (this.mImageListView.hScrollBar.Visible)
			{
				this.mClientArea.Height = this.mClientArea.Height - this.mImageListView.hScrollBar.Height;
				this.mItemAreaBounds.Height = this.mItemAreaBounds.Height - this.mImageListView.hScrollBar.Height;
			}
			if (this.mImageListView.vScrollBar.Visible)
			{
				this.mClientArea.Width = this.mClientArea.Width - this.mImageListView.vScrollBar.Width;
				this.mItemAreaBounds.Width = this.mItemAreaBounds.Width - this.mImageListView.vScrollBar.Width;
			}
			if (this.mImageListView.View == View.Details)
			{
				int num = this.cachedHeaderHeight;
				this.mColumnHeaderBounds.X = this.mClientArea.Left - this.mImageListView.ViewOffset.X;
				this.mColumnHeaderBounds.Y = this.mClientArea.Top;
				this.mColumnHeaderBounds.Height = num;
				this.mColumnHeaderBounds.Width = this.mClientArea.Width + this.mImageListView.ViewOffset.X;
				this.mItemAreaBounds.Y = this.mItemAreaBounds.Y + num;
				this.mItemAreaBounds.Height = this.mItemAreaBounds.Height - num;
			}
			else
			{
				this.mColumnHeaderBounds = Rectangle.Empty;
			}
			if (this.mImageListView.View == View.Gallery)
			{
				this.mItemAreaBounds.Height = this.mItemSizeWithMargin.Height;
				this.mItemAreaBounds.Y = this.mClientArea.Bottom - this.mItemSizeWithMargin.Height;
			}
			if (this.mImageListView.View == View.Pane)
			{
				this.mItemAreaBounds.Width = this.mItemAreaBounds.Width - this.cachedPaneWidth;
				this.mItemAreaBounds.X = this.mItemAreaBounds.X + this.cachedPaneWidth;
			}
			if (this.mItemAreaBounds.Width < 1 || this.mItemAreaBounds.Height < 1)
			{
				return;
			}
			LayoutEventArgs layoutEventArgs = new LayoutEventArgs(this.mItemAreaBounds);
			this.mImageListView.mRenderer.OnLayout(layoutEventArgs);
			this.mItemAreaBounds = layoutEventArgs.ItemAreaBounds;
			this.mCols = (int)Math.Floor((double)((float)this.mItemAreaBounds.Width / (float)this.mItemSizeWithMargin.Width));
			this.mRows = (int)Math.Floor((double)((float)this.mItemAreaBounds.Height / (float)this.mItemSizeWithMargin.Height));
			if (this.mImageListView.View == View.Details)
			{
				this.mCols = 1;
			}
			if (this.mImageListView.View == View.Gallery)
			{
				this.mRows = 1;
			}
			if (this.mCols < 1)
			{
				this.mCols = 1;
			}
			if (this.mRows < 1)
			{
				this.mRows = 1;
			}
			bool flag;
			if (this.mImageListView.View == View.Gallery)
			{
				flag = (this.mImageListView.Items.Count > 0 && this.mCols * this.mRows < this.mImageListView.Items.Count);
			}
			else
			{
				flag = (this.mImageListView.Items.Count > 0 && this.mItemAreaBounds.Width < this.mCols * this.mItemSizeWithMargin.Width);
			}
			if (flag != this.hScrollVisible)
			{
				this.hScrollVisible = flag;
				this.mImageListView.hScrollBar.Visible = flag;
				this.Update(true);
				return;
			}
			bool flag2;
			if (this.mImageListView.View == View.Gallery)
			{
				flag2 = (this.mImageListView.Items.Count > 0 && this.mItemAreaBounds.Height < this.mRows * this.mItemSizeWithMargin.Height);
			}
			else
			{
				flag2 = (this.mImageListView.Items.Count > 0 && this.mCols * this.mRows < this.mImageListView.Items.Count);
			}
			if (flag2 != this.vScrollVisible)
			{
				this.vScrollVisible = flag2;
				this.mImageListView.vScrollBar.Visible = flag2;
				this.Update(true);
				return;
			}
			if (this.mImageListView.View == View.Gallery)
			{
				this.mImageListView.hScrollBar.SmallChange = this.mItemSizeWithMargin.Width;
				this.mImageListView.hScrollBar.LargeChange = this.mItemAreaBounds.Width;
				this.mImageListView.hScrollBar.Minimum = 0;
				this.mImageListView.hScrollBar.Maximum = Math.Max(0, (int)Math.Ceiling((double)((float)this.mImageListView.Items.Count / (float)this.mRows)) * this.mItemSizeWithMargin.Width - 1);
			}
			else
			{
				this.mImageListView.hScrollBar.SmallChange = 1;
				this.mImageListView.hScrollBar.LargeChange = this.mItemAreaBounds.Width;
				this.mImageListView.hScrollBar.Minimum = 0;
				this.mImageListView.hScrollBar.Maximum = this.mCols * this.mItemSizeWithMargin.Width;
			}
			if (this.mImageListView.ViewOffset.X > this.mImageListView.hScrollBar.Maximum - this.mImageListView.hScrollBar.LargeChange + 1)
			{
				this.mImageListView.hScrollBar.Value = this.mImageListView.hScrollBar.Maximum - this.mImageListView.hScrollBar.LargeChange + 1;
				this.mImageListView.ViewOffset = new Point(this.mImageListView.hScrollBar.Value, this.mImageListView.ViewOffset.Y);
			}
			if (this.mImageListView.View == View.Gallery)
			{
				this.mImageListView.vScrollBar.SmallChange = 1;
				this.mImageListView.vScrollBar.LargeChange = this.mItemAreaBounds.Height;
				this.mImageListView.vScrollBar.Minimum = 0;
				this.mImageListView.vScrollBar.Maximum = this.mRows * this.mItemSizeWithMargin.Height;
			}
			else
			{
				this.mImageListView.vScrollBar.SmallChange = this.mItemSizeWithMargin.Height;
				this.mImageListView.vScrollBar.LargeChange = this.mItemAreaBounds.Height;
				this.mImageListView.vScrollBar.Minimum = 0;
				this.mImageListView.vScrollBar.Maximum = Math.Max(0, (int)Math.Ceiling((double)((float)this.mImageListView.Items.Count / (float)this.mCols)) * this.mItemSizeWithMargin.Height - 1);
			}
			if (this.mImageListView.ViewOffset.Y > this.mImageListView.vScrollBar.Maximum - this.mImageListView.vScrollBar.LargeChange + 1)
			{
				this.mImageListView.vScrollBar.Value = this.mImageListView.vScrollBar.Maximum - this.mImageListView.vScrollBar.LargeChange + 1;
				this.mImageListView.ViewOffset = new Point(this.mImageListView.ViewOffset.X, this.mImageListView.vScrollBar.Value);
			}
			if (this.mImageListView.Items.Count == 0)
			{
				this.mImageListView.hScrollBar.Minimum = 0;
				this.mImageListView.hScrollBar.Maximum = 0;
				this.mImageListView.hScrollBar.Value = 0;
				this.mImageListView.vScrollBar.Minimum = 0;
				this.mImageListView.vScrollBar.Maximum = 0;
				this.mImageListView.vScrollBar.Value = 0;
				this.mImageListView.ViewOffset = new Point(0, 0);
			}
			this.mImageListView.hScrollBar.Left = 0;
			this.mImageListView.hScrollBar.Top = this.mImageListView.ClientRectangle.Bottom - this.mImageListView.hScrollBar.Height;
			this.mImageListView.hScrollBar.Width = this.mImageListView.ClientRectangle.Width - (this.mImageListView.vScrollBar.Visible ? this.mImageListView.vScrollBar.Width : 0);
			this.mImageListView.vScrollBar.Left = this.mImageListView.ClientRectangle.Right - this.mImageListView.vScrollBar.Width;
			this.mImageListView.vScrollBar.Top = 0;
			this.mImageListView.vScrollBar.Height = this.mImageListView.ClientRectangle.Height - (this.mImageListView.hScrollBar.Visible ? this.mImageListView.hScrollBar.Height : 0);
			if (this.mImageListView.View == View.Gallery)
			{
				this.mFirstPartiallyVisible = (int)Math.Floor((double)((float)this.mImageListView.ViewOffset.X / (float)this.mItemSizeWithMargin.Width)) * this.mRows;
				this.mLastPartiallyVisible = (int)Math.Ceiling((double)((float)(this.mImageListView.ViewOffset.X + this.mItemAreaBounds.Width) / (float)this.mItemSizeWithMargin.Width)) * this.mRows - 1;
			}
			else
			{
				this.mFirstPartiallyVisible = (int)Math.Floor((double)((float)this.mImageListView.ViewOffset.Y / (float)this.mItemSizeWithMargin.Height)) * this.mCols;
				this.mLastPartiallyVisible = (int)Math.Ceiling((double)((float)(this.mImageListView.ViewOffset.Y + this.mItemAreaBounds.Height) / (float)this.mItemSizeWithMargin.Height)) * this.mCols - 1;
			}
			if (this.mFirstPartiallyVisible < 0)
			{
				this.mFirstPartiallyVisible = 0;
			}
			if (this.mFirstPartiallyVisible > this.mImageListView.Items.Count - 1)
			{
				this.mFirstPartiallyVisible = this.mImageListView.Items.Count - 1;
			}
			if (this.mLastPartiallyVisible < 0)
			{
				this.mLastPartiallyVisible = 0;
			}
			if (this.mLastPartiallyVisible > this.mImageListView.Items.Count - 1)
			{
				this.mLastPartiallyVisible = this.mImageListView.Items.Count - 1;
			}
			if (this.mImageListView.View == View.Gallery)
			{
				this.mFirstVisible = (int)Math.Ceiling((double)((float)this.mImageListView.ViewOffset.X / (float)this.mItemSizeWithMargin.Width)) * this.mRows;
				this.mLastVisible = (int)Math.Floor((double)((float)(this.mImageListView.ViewOffset.X + this.mItemAreaBounds.Width) / (float)this.mItemSizeWithMargin.Width)) * this.mRows - 1;
			}
			else
			{
				this.mFirstVisible = (int)Math.Ceiling((double)((float)this.mImageListView.ViewOffset.Y / (float)this.mItemSizeWithMargin.Height)) * this.mCols;
				this.mLastVisible = (int)Math.Floor((double)((float)(this.mImageListView.ViewOffset.Y + this.mItemAreaBounds.Height) / (float)this.mItemSizeWithMargin.Height)) * this.mCols - 1;
			}
			if (this.mFirstVisible < 0)
			{
				this.mFirstVisible = 0;
			}
			if (this.mFirstVisible > this.mImageListView.Items.Count - 1)
			{
				this.mFirstVisible = this.mImageListView.Items.Count - 1;
			}
			if (this.mLastVisible < 0)
			{
				this.mLastVisible = 0;
			}
			if (this.mLastVisible > this.mImageListView.Items.Count - 1)
			{
				this.mLastVisible = this.mImageListView.Items.Count - 1;
			}
			if (this.mFirstPartiallyVisible >= 0 && this.mLastPartiallyVisible >= 0 && this.mFirstPartiallyVisible <= this.mImageListView.Items.Count - 1 && this.mLastPartiallyVisible <= this.mImageListView.Items.Count - 1)
			{
				for (int i = this.mFirstPartiallyVisible; i <= this.mLastPartiallyVisible; i++)
				{
					this.cachedVisibleItems.Add(this.mImageListView.Items[i].Guid, false);
				}
			}
		}

		public bool IsItemVisible(Guid guid)
		{
			return this.cachedVisibleItems.ContainsKey(guid);
		}

		private Rectangle mClientArea;

		private ImageListView mImageListView;

		private Rectangle mItemAreaBounds;

		private Rectangle mColumnHeaderBounds;

		private Size mItemSize;

		private Size mItemSizeWithMargin;

		private int mCols;

		private int mRows;

		private int mFirstPartiallyVisible;

		private int mLastPartiallyVisible;

		private int mFirstVisible;

		private int mLastVisible;

		private View cachedView;

		private Point cachedViewOffset;

		private Size cachedSize;

		private int cachedItemCount;

		private Size cachedItemSize;

		private int cachedHeaderHeight;

		private Size cachedItemMargin;

		private int cachedPaneWidth;

		private Dictionary<Guid, bool> cachedVisibleItems;

		private bool vScrollVisible;

		private bool hScrollVisible;
	}
}
